<?php namespace nimo\common\csv;

use RuntimeException;

class Exporter {

    private $configs = array();
    private $filename;
    private $interceptor = null;
    private $csv_handle = null;

    public function __construct($filename, $configs = array(), ExportInterceptor $interceptor) 
    {
        $this->filename = $filename;
        $this->interceptor = $interceptor;
        // 区切り文字
        $this->configs['delimiter']   = isset($configs['delimiter']) ? $configs['delimiter'] : ',';
        // 囲み文字
        $this->configs['enclosure']   = isset($configs['enclosure']) ? $configs['enclosure'] : '"';
        // エスケープ文字
        $this->configs['escape']      = isset($configs['escape']) ? $configs['escape'] : '\\';
        // 読込文字コード
        $this->configs['fromCharset'] = isset($configs['fromCharset']) ? $configs['fromCharset'] : 'UTF-8';
        // 書込文字コード
        $this->configs['toCharset']   = isset($configs['toCharset']) ? $configs['toCharset'] : 'UTF-8';
        // ファイルモード
        $this->configs['mode']        = isset($configs['mode']) ? $configs['mode'] : 'w';
        // ファイルモード
        $this->configs['newLine']     = isset($configs['newLine']) ? $configs['newLine'] : "\n";
    }

    public function execute() {
        if (($this->csv_handle = fopen($this->filename,$this->configs['mode'])) === false){
            throw new RuntimeException('Failed to open file: '.$this->filename);
        }
        $this->interceptor->export($this);
        fclose($this->csv_handle);
    }

    public function export($datas) {
        $fromCharset = $this->configs['fromCharset'];
        $toCharset = $this->configs['toCharset'];
        $line= self::make_csv_line($datas, $this->configs['delimiter'], $this->configs['enclosure'], $this->configs['escape']);
        if ($fromCharset != $toCharset) {
            $line=mb_convert_encoding($line, $toCharset, $fromCharset);
        }
        fwrite($this->csv_handle, $line);
        fwrite($this->csv_handle, $this->configs['newLine']);
    }

    public static function make_csv_line($values, $delimiter, $enclosure, $escape){
        $datas = array();
        foreach($values as $i =>$value) {
            if ((strpos($value, ',') !== false) ||
                (strpos($value, '"') !== false) ||
                (strpos($value, ' ') !== false) ||
                (strpos($value, "\t") !== false) ||
                (strpos($value, "\n") !== false) ||
                (strpos($value, "\r") !== false)) {
                $datas[$i] = $enclosure . str_replace('"', '""', $value) . $enclosure;
            } else {
                $datas[$i] = $value;
            }
        }
        return implode($delimiter,$datas);
    }
}
